<template>
  <div class="ws-record">
    <!-- 实时语音 -->
    <div class="box-right">
      <div class="real-time-status">
        <p :class="recording ? 'danger-color' : 'primary-color'">
          {{ recording ? "广播中" : "未广播" }}
        </p>
        <p>
          <span
            class="video-icon"
            :class="recording ? 'el-icon-video-pause' : 'el-icon-video-play'"
            @click="changeStatus(recording ? 'stop' : 'start')"
          ></span>
        </p>
        <p>{{ recording ? "点击停止广播" : "点击开始广播" }}</p>
      </div>
      <!-- <canvas id="casvased" style="width: 200px;height: 50px"></canvas> -->
    </div>
  </div>
</template>

<script>
import MP3Recorder from "@/js/recordmp3";
export default {
  name: "WsRecord",
  data() {
    return {
      microphone: "local", // 选中麦克风
      recording: false, // 实时广播是否播放中
      ws: null, // websocket实例
      recorder: null,
      reader: null,
    };
  },
  methods: {
    // 改变广播状态
    changeStatus(type) {
      // start 开始  stop 停止 volume调整声音
      if (type === "start") {
        this.start();
      } else if (type === "stop") {
        this.stop();
      }
    },
    // 开始广播
    start() {
      if (!this.microphone) {
        this.$message.error("请先选择麦克风设备");
        return;
      }
      // 开始本机录音设备实时广播
      this.recording = true;
      this.initWs();
    },

    // 暂停广播
    async stop() {
      // 本机广播
      if (this.ws) {
        this.recorder?.stop?.();
        this.recorder = null;
        if (this.ws.readyState === this.ws.OPEN) {
          this.ws.send(JSON.stringify({ action: "0" }));
          this.ws.close();
        }
        console.log("关闭对讲以及WebSocket");
        this.recording = false;
      }
    },
    // 暂停本机录音设备实时广播
    async stopRecBroadcast() {},
    // 初始化ws
    initWs() {
      if (this.ws && this.ws.readyState === this.ws.OPEN) {
        this.ws?.close?.();
      }
      this.ws = new WebSocket('ws://10.10.2.165:8180/recordingWsHandler');
      this.ws.binaryType = "arraybuffer";
      this.ws.onopen = () => {
        console.log("握手成功");
        console.log(this.ws, "this.ws");
        if (this.ws.readyState === this.ws.OPEN) {
          //ws进入连接状态, 初始化readerFile, 初始化录音
          this.initReader();
          this.initRecord();
        }
      };
      this.ws.onmessage = function (msg) {
        console.info(msg);
      };
      this.ws.onerror = function (err) {
        console.info(err);
        this.recording = false;
      };
    },
    // 初始化recorder
    initRecord() {
      // const canvas = document.getElementById("casvased");
      // const canvasCtx = canvas.getContext("2d")
      this.recorder = new MP3Recorder({
        debug: true,
        // canvasWidth: 400,
        // canvasHeight: 100,
        // canvasCtx: canvasCtx,
        funOk: () => {
          console.log("初始化成功");
          this.recorder?.start?.();
          this.recorder?.draw?.();
          this.recording = true;
        },
        funCancel: (msg) => {
          this.recorder = null;
          this.ws?.close?.();
          this.recording = false;
          this.$message.error(`录音开启失败：${msg}`);
        },
        funAudioprocess: this.sentData,
      });
    },
    // 初始化FileReader
    initReader() {
      //对以获取的数据进行处理(分包)
      this.reader = new FileReader();
      const _this = this;
      this.reader.onload = (e) => {
        let outbuffer = e.target.result;
        let arr = new Int8Array(outbuffer);
        if (arr.length > 0) {
          let tmparr = new Int8Array(1024);
          let j = 0;
          for (let i = 0; i < arr.byteLength; i++) {
            tmparr[j++] = arr[i];
            if ((i + 1) % 1024 == 0) {
              //ws处于连接状态
              if (_this.ws?.readyState == 1) {
                _this.ws?.send?.(tmparr);
              }
              if (arr.byteLength - i - 1 >= 1024) {
                tmparr = new Int8Array(1024);
              } else {
                tmparr = new Int8Array(arr.byteLength - i - 1);
              }
              j = 0;
            }
            if (i + 1 == arr.byteLength && (i + 1) % 1024 != 0) {
              //ws处于连接状态
              if (_this.ws?.readyState == 1) {
                _this.ws?.send?.(tmparr);
              }
            }
          }
        }
      };
    },
    // 发送音频流
    sentData() {
      //对以获取的数据进行处理(分包)
      this.recorder?.getMp3Blob?.((blob) => {
        this.reader?.readAsArrayBuffer?.(blob); //这里拿到mp3格式的音频流写入到reader中
      });
    },
  },
  beforeDestroy() {
    if (this.recording) {
      this.stop();
    }
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
@deep: ~">>>";
.ws-record {
  display: flex;
  .box-left {
    width: 180px;
    max-height: 300px;
    overflow: auto;
    padding: 15px;
    border-right: 1px solid #e5e5e5;
    .box-title {
      color: #6199e6;
    }
    .radio-position {
      display: flex;
      flex-direction: column;
      margin-top: 15px;
      max-height: 300px;
      overflow: auto;
      .radio-item {
        margin: 5px 0;
        .label {
          display: inline-block;
          max-width: 120px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          line-height: 14px;
        }
        .microphone-icon {
          font-size: 18px;
          color: #6199e6;
          line-height: 14px;
        }
        @deep {
          .el-radio__input {
            line-height: 20px;
          }
        }
      }
    }
  }
  .box-right {
    flex: 1;
    display: flex;
    flex-direction: column;
    .real-time-status {
      flex: 1;
      text-align: center;
      padding: 40px 0;
      display: flex;
      flex-direction: column;
      justify-content: center;
      .video-icon {
        font-size: 80px;
        margin: 15px 0;
        cursor: pointer;
      }
      .el-icon-video-pause {
        color: #fd7b7b;
      }
      .el-icon-video-play {
        color: #6199e6;
      }
    }

    .real-time-volume {
      border-top: 1px solid #e5e5e5;
      padding: 15px;
      display: flex;
      line-height: 38px;
      .volume-slider {
        flex: 1;
        margin-left: 15px;
      }
    }
  }
}
.primary-color {
  color: #6199e6;
}
.danger-color {
  color: #fd7b7b;
}
</style>
